home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
assemblr
/
library
/
sampler0
/
listmo.asm
< prev
next >
Wrap
Assembly Source File
|
1979-12-31
|
25KB
|
904 lines
name list
page 55,132
title 'LIST --- Print text file'
; LIST --- a utility to print out text files with titles and page
; numbers on the current list device. The high bit of all
; characters is stripped, so that raw Wordstar or other word
; processing files can be listed. Embedded form feed codes are
; recognized, and tabs are expanded. Unknown control codes (such
; as the ^B and ^U codes found in Wordstar documents) are discarded.
; If using an Epson printer, compressed mode can be turned on with
; /C switch in command so that lines up to 128 characters long will
; fit on a normal page. Requires PC-DOS 2.0 or MS-DOS 2.0.
; Used in the form:
; A>LIST path\filename.ext ["title text"] [/C] [/D] [/E]
; (items in square brackets are optional)
; version 1.0 February 28, 1984
; Copyright (c) 1984 by Ray Duncan
; May be freely reproduced for non-commercial use.
; version 1.1 April 8, 1985
; by M. Michael Shabot, M.D.
; added two print options: /E for Epson "emphasised" print mode
; /D for Epson "double strike" mode
; [the /C /D and /E switches may be used in any combination,
; although /E (pica-sized) will override /C (condensed)]
cr equ 0dh ;ASCII carriage return
lf equ 0ah ;ASCII line feed
ff equ 0ch ;ASCII form feed
eof equ 01ah ;End of file marker
tab equ 09h ;ASCII tab character
command equ 80h ;buffer for command tail
blksize equ 1024 ;size of block reads from input file
linesize equ 132 ;maximum length of output line
pagesize equ 58 ;number of lines per page
heading_lines equ 3 ;number of lines in page heading
output_handle equ 4 ;handle of standard list device
cseg segment para public 'CODE'
assume cs:cseg,ds:data,es:data,ss:stack
list proc far ;entry point from PC-DOS
push ds ;save DS:0000 for final
xor ax,ax ;return to PC-DOS
push ax
mov ax,data ;make our data segment
mov es,ax ;addressable via ES register.
call get_title ;get listing title from
;command line tail.
call get_switch ;look for /C switch if any
call get_emphasis ;look for /E switch if any
call get_doublestrike;look for /D switch if any
call get_filename ;get path and file spec. for
;input file from command line tail.
mov ax,es ;set DS=ES for remainder
mov ds,ax ;of program.
jnc list13 ;jump, got acceptable name.
mov dx,offset msg2 ;missing or illegal filespec,
jmp list9 ;print error message and exit.
list13: ;make sure we're running under DOS 2.0.
mov ah,30h
int 21h
cmp al,2
jae list15 ;proceed, DOS 2.0 or greater
mov dx,offset msg3 ;DOS 1.x --- print error message
jmp list9
list15: call open_input ;now try to open input file
jnc list2 ;jump,opened input ok
mov dx,offset msg1 ;open of input file failed,
jmp list9 ;print error msg and exit.
list2:
test compress_switch,-1 ;was /C switch found?
jz list65 ;no,jump
call compress_on ;yes,turn on compressed print mode
list65:
test emphasis_switch,-1 ;was /E switch found?
jz list66 ;no,jump
call emphasis_on ;yes,turn on emphasised print mode
list66:
test doublestrike_switch,-1 ;was /D switch found?
jz list25 ;no,jump
call doublestrike_on ;yes,turn on doublestrike print mode
list25: call init_buff ;initialize input deblocking buffer
;file successfully opened,
list3: ;now print it!
call get_char ;read 1 character from input.
and al,07fh ;strip off the high bit
cmp al,20h ;is it a control code?
jae list4 ;no,write it to list device.
;yes it is control code,
cmp al,eof ;is it end of file marker?
je list8 ;yes,jump to close files.
cmp al,tab ;is it a tab command?
je list5 ;yes,jump to special processing.
cmp al,ff ;is it a form feed?
je list6 ;yes, jump to special processing.
cmp al,lf ;is it a line feed?
je list7 ;yes,jump to special processing.
cmp al,cr ;if illegal control code,
jne list3 ;discard it and get next char.
mov column,0 ;if carriage return, store it into output
jmp list45 ;string and initialize column count.
list4: ;count chars. sent on this line.
inc column
list45: ;write this character into
call put_char ;forming output string.
;is output buffer about to overflow?
cmp output_ptr,linesize-1
je list7 ;yes, force print of buffer.
jmp list3 ;no, get next char. from input file.
list5: ;process tab character
mov ax,column ;let DX:AX=column count
cwd
mov cx,8 ;divide it by eight...
idiv cx
sub cx,dx ;remainder is in DX.
add column,cx ;update column pointer.
list55: ;8 minus the remainder
push cx ;gives us the number of
mov al,20h ;spaces to send out to
call put_char ;move to the next tab position
pop cx ;restore space count
loop list55
jmp short list3 ;get next character
list6: ;form feed detected
call write_maybe ;if anything waiting in output
;buffer, print it first
call print_heading ;new page and print title
jmp list3 ;get next character from input
list7: ;line feed detected, interpreted
;as print command.
call heading_maybe ;print heading if needed
call write_line ;print contents of text buffer
jmp list3 ;get more from input file
list8: ;end of file detected,
call write_maybe ;print anything that's waiting
;in output buffer.
mov al,ff ;send form feed to finish listing.
call put_char
call write_line
call close_input ;close input file.
;turn off compressed print mode,
;if it was enabled.
test compress_switch,-1
jz list75
call compress_off
list75: ;turn off emphasised print mode,
;if it was enabled.
test emphasis_switch,-1
jz list76
call emphasis_off
list76: ;turn off doublestrike print mode,
;if it was enabled.
test doublestrike_switch,-1
jz list85
call doublestrike_off
list85: ret ;now return to PC-DOS.
list9: ;come here to print error message
mov ah,9 ;and return control to PC-DOS
int 21h
ret
list endp
get_filename proc near ;process name of input file
;DS:SI <- addr command line
mov si,offset command
;ES:DI <- addr filespec buffer
mov di,offset input_name
cld
lodsb ;any command line present?
or al,al ;return error status if not.
jz get_filename4
get_filename1: ;scan over leading blanks
lodsb ;to file name
cmp al,cr ;if we hit carriage return
je get_filename4
cmp al,'/' ;or switch,
je get_filename4
cmp al,'"' ;or quote mark, filename missing.
je get_filename4 ;so go return error flag.
cmp al,20h ;is this a blank?
jz get_filename1 ;if so keep scanning.
get_filename2: ;found first char of name,
stosb ;move last char. to output
;file name buffer.
lodsb ;check next character, found
cmp al,cr ;carriage return yet?
je get_filename3 ;yes,exit with success code.
cmp al,'"' ;same if quote encountered.
je get_filename3
cmp al,20h ;is this a blank?
jne get_filename2 ;if not keep moving chars.
get_filename3: ;exit with carry =0
clc ;for success flag
ret
get_filename4: ;exit with carry =1
stc ;for error flag
ret
get_filename endp
get_title proc near ;process title for listing
;DS:SI <- addr command line
mov si,offset command
;ES:DI <- addr page heading buffer
mov di,offset heading1
cld
lodsb ;any command line present?
or al,al ;no,exit
jz get_title3
get_title1: ;scan for leading <"> to find title.
lodsb
cmp al,cr ;if we hit carriage return,
je get_title3 ;title text is missing.
cmp al,'"' ;found delimiter?
jne get_title1 ;if so keep scanning.
get_title2: ;get next char. of title.
lodsb
cmp al,'"' ;terminate if 2nd <"> delimiter
je get_title3 ;or carriage return found
cmp al,cr
je get_title3
stosb ;store this char. into page heading buffer
jmp get_title2 ;examine next char.
get_title3:
ret
get_title endp
get_switch proc near ;Scan the input line for a "/"
;delimiting a switch, then make
;sure it is legal "/C" or "/c".
;If legal switch found, set
;variable COMPRESS_SWITCH true.
mov si,offset command+1 ; DS:SI = addr of command line
get_switch1: ;look for "/" character
lodsb
cmp al,cr ;if we run into a carriage return,
jz get_switch2 ;switch missing so take normal exit.
cmp al,'/'
jne get_switch1 ;not '/' yet, keep looking.
lodsb ;found '/', pick up next char.
or al,20h ;and fold to lower case.
cmp al,'c' ;c=compress
jne get_switch1 ;not c, jump
;set compress switch
mov es:compress_switch,-1
get_switch2:
ret ;exit
get_switch endp
get_emphasis proc near ;Scan the input line for a "/"
;delimiting a switch, then make
;sure it is legal "/E" or "/e".
;If legal switch found, set
;variable EMPHASIS_SWITCH true.
mov si,offset command+1 ; DS:SI = addr of command line
get_emphasis1: ;look for "/" character
lodsb
cmp al,cr ;if we run into a carriage return,
jz get_emphasis2 ;switch missing so take normal exit.
cmp al,'/'
jne get_emphasis1 ;not '/' yet, keep looking.
lodsb ;found '/', pick up next char.
or al,20h ;and fold to lower case.
cmp al,'e' ;e=emphasis
jne get_emphasis1 ;not e, jump
;set emphasis switch
mov es:emphasis_switch,-1
get_emphasis2:
ret ;exit
get_emphasis endp
get_doublestrike proc near ;Scan the input line for a "/"
;delimiting a switch, then make
;sure it is legal "/D" or "/d".
;If legal switch found, set
;variable DOUBLESTRIKE_SWITCH true.
mov si,offset command+1 ; DS:SI = addr of command line
get_doublestrike1: ;look for "/" character
lodsb
cmp al,cr ;if we run into a carriage return,
jz get_doublestrike2 ;switch missing so take normal exit.
cmp al,'/'
jne get_doublestrike1 ;not '/' yet, keep looking.
lodsb ;found '/', pick up next char.
or al,20h ;and fold to lower case.
cmp al,'d' ;d=doublestrike
jne get_doublestrike1 ;not d, jump
;set doublestrike switch
mov es:doublestrike_switch,-1
get_doublestrike2:
ret ;exit
get_doublestrike endp
open_input proc near ;open input file
;DS:DX=addr filename
mov dx,offset input_name
mov al,0 ;AL=0 for read only
mov ah,3dh ;function 3dh=open
int 21h ;handle returned in AX,
mov input_handle,ax ;save it for later.
ret ;CY is set if error
open_input endp
close_input proc near ;close input file
mov bx,input_handle ;BX=handle
mov ah,3eh
int 21h
ret
close_input endp
get_char proc near ;get one character from input buffer
mov bx,input_ptr ;is pointer at end of buffer?
cmp bx,blksize
jne get_char1 ;no,jump
;yes, buffer is exhausted,
call read_block ;new block must be read from disk.
mov bx,0 ;initialize buffer pointer.
get_char1:
mov al,[input_buffer+bx]
inc bx ;bump input buffer pointer
mov input_ptr,bx
ret
get_char endp
put_char proc near ;put one character into output buffer
mov bx,output_ptr
mov [output_buffer+bx],al
inc output_ptr ;bump pointer to output string
ret
put_char endp
read_block proc near ;read block of data from input file.
mov bx,input_handle
mov cx,blksize
mov dx,offset input_buffer
mov ah,3fh
int 21h
jnc read_block1 ;jump if no error status
mov ax,0 ;simulate a zero length read if error
read_block1:
cmp ax,blksize ;was full buffer read in?
je read_block2 ;yes,jump
mov bx,ax ;no, store End-of-File mark
mov byte ptr [input_buffer+bx],eof
read_block2:
mov input_ptr,0 ;initialize pointer to input buffer.
ret
read_block endp
write_maybe proc near ;transmit line to list device, if
;output buffer contains anything.
mov ax,output_ptr ;pointer is non-zero if characters
or ax,ax ;are waiting in buffer.
jz write_maybe1 ;nothing, jump to exit
call write_line ;something there, send it to printer
write_maybe1:
ret
write_maybe endp
write_line proc near ;transmit contents of output
;buffer to the standard list device.
mov al,lf ;append line feed to string.
call put_char
mov cx,output_ptr ;CX contains length of string
;DX:DX=buffer address
mov dx,offset output_buffer
mov bx,output_handle;BX=handle for standard list device.
mov ah,40h ;function 40h=write to device.
int 21h ;request service from DOS.
inc linecount ;count lines printed this page.
mov output_ptr,0 ;reset pointer to list device buffer
ret
write_line endp
heading_maybe proc near ;print heading if the line
;count justifies it
cmp linecount,pagesize
jl heading_maybe2 ;jump,page not full yet
call print_heading ;form feed and print title
heading_maybe2:
ret
heading_maybe endp
print_heading proc near ;print form feed, title, and page no.
inc pagecount ;bump page number,
mov ax,pagecount ;load it,
aam ;and turn it into ASCII,
add ax,'00'
mov heading2,ah ;then store into heading string.
mov heading2+1,al
;now print the heading string.
mov dx,offset heading_buffer
mov cx,heading_length
mov bx,output_handle
mov ah,40h
int 21h
;initialize line count
mov linecount,heading_lines
mov column,0 ;and column counter
ret
print_heading endp
init_buff proc near ;initialize i/o buffers
call read_block ;read 1st block of input file
mov output_ptr,0 ;initialize pointer to output string
ret
init_buff endp
compress_on proc near ;turn on compressed printing mode
;by sending command string.
mov cx,comp_command_length
mov bx,output_handle
mov dx,offset comp_command
mov ah,40h
int 21h
ret
compress_on endp
compress_off proc near ;turn off compressed printing mode
;by sending command string.
mov cx,norm_command_length
mov bx,output_handle
mov dx,offset norm_command
mov ah,40h
int 21h
ret
compress_off endp
emphasis_on proc near ;turn on emphasised printing mode
;by sending command string.
mov cx,emphasis_on_command_length
mov bx,output_handle
mov dx,offset emphasis_on_command
mov ah,40h
int 21h
ret
emphasis_on endp
emphasis_off proc near ;turn off emphasised printing mode
;by sending command string.
mov cx,emphasis_off_command_length
mov bx,output_handle
mov dx,offset emphasis_off_command
mov ah,40h
int 21h
ret
emphasis_off endp
doublestrike_on proc near ;turn on doublestrike printing mode
;by sending command string.
mov cx,doublestrike_on_command_length
mov bx,output_handle
mov dx,offset doublestrike_on_command
mov ah,40h
int 21h
ret
doublestrike_on endp
doublestrike_off proc near ;turn off doublestrike printing mode
;by sending command string.
mov cx,doublestrike_off_command_length
mov bx,output_handle
mov dx,offset doublestrike_off_command
mov ah,40h
int 21h
ret
doublestrike_off endp
cseg ends
data segment para public 'DATA'
input_name db 64 dup (0) ;buffer for input filespec
input_handle dw 0 ;token from PCDOS for input file.
input_ptr dw 0 ;pointer to input blocking buffer
output_ptr dw 0 ;pointer to output blocking buffer
column dw 0 ;column count for tab processing
linecount dw pagesize ;line counter, current page.
;(set to "pagesize" initially to
;force first heading on listing)
pagecount dw 0 ;current page number
compress_switch dw 0 ;set to -1 if /C switch
;found in command line tail.
comp_command db 0fh ;command string for compressed mode
comp_command_length equ $-comp_command
norm_command db 12h ;command string for normal print
norm_command_length equ $-norm_command
emphasis_switch dw 0 ;set to -1 if /E switch
;found in command line tail.
emphasis_on_command db 1Bh,45h ;command string for emphasised mode
emphasis_on_command_length equ $-emphasis_on_command
emphasis_off_command db 1Bh,46h ;command string for non-emphasised print
emphasis_off_command_length equ $-emphasis_off_command
doublestrike_switch dw 0 ;set to -1 if /D switch
;found in command line tail.
doublestrike_on_command db 1Bh,47h ;command string for doublestrike mode
doublestrike_on_command_length equ $-doublestrike_on_command
doublestrike_off_command db 1Bh,48h ;command string for non-doublestrike print
doublestrike_off_command_length equ $-doublestrike_off_command
msg1 db cr,lf
db 'Cannot find file to be printed.'
db cr,lf,'$'
msg2 db cr,lf
db 'Missing file name.'
db cr,lf,'$'
msg3 db cr,lf
db 'Requires PC-DOS version 2 or greater.'
db cr,lf,'$'
input_buffer db blksize dup (?) ;deblocking buffer for input file
output_buffer db linesize dup (?);buffer used to build output
;lines for list device
heading_buffer db ff ;form feed control code
heading1 db 60 dup (' ') ;filled in with title from user
db 'Page '
heading2 db '00',cr
db heading_lines dup (lf)
heading_length equ $-heading_buffer
data ends
stack segment para stack 'STACK'
db 64 dup (?)
stack ends
end list
Press ENTER to continue:
Press ENTER to continue